#include "global_val.h"

int g_msgid=-1;
int g_sem_id;

/*********************************************************************
 * @fn      sys_error
 *
 * @brief   使用perror函数打印出当前错误信息
 *
 * @param   const char *str:传入参数，错误提示信息
 *
 * @return  none
 */
void sys_error(const char *str)
{
	perror(str);
	exit(1);
}

/*********************************************************************
 * @fn      sys_error
 *
 * @brief   使用strerror函数打印出当前错误信息
 *
 * @param   const char *str:传入参数，错误提示信息
 *            const int ret:传入参数，错误信息号
 *
 * @return  none
 */
void sys_error_num(const char *str, const int ret)
{
	printf("%s fail:%s\n", str, strerror(ret));
	exit(1);
}

/*********************************************************************
 * @fn      poperation
 *
 * @brief   P操作，对信号集semid中的第index个信号量执行 -1 操作
 *
 * @param   const int index:传入参数，信号量编号
 *          const int semid:传入参数，信号集ID
 *
 * @return  none
 */
void poperation(const int index, const int semid) //传入要操作的信号量，信号量集
{
	//初始化sembuf结构体
	struct sembuf sop;
	sop.sem_num = index; //信号量编号
	sop.sem_op  = -1;    //P操作:-1
	sop.sem_flg =  0;    //SEM_UNDO

	//信号量集ID,对信号量操作的结构体，操作的信号量个数
	semop(semid,&sop,1);
}

/*********************************************************************
 * @fn      voperation
 *
 * @brief   V操作，对信号集semid中的第index个信号量执行 +1 操作
 *
 * @param   const int index:传入参数，信号量编号
 *          const int semid:传入参数，信号集ID
 *
 * @return  none
 */
void voperation(int index, int semid)
{
	//初始化sembuf结构体
	struct sembuf sop;
	sop.sem_num = index; //信号量编号
	sop.sem_op  =  1;    //V操作:1
	sop.sem_flg =  0;    //SEM_UNDO

	//信号量集ID,对信号量操作的结构体，操作的信号量个数
	semop(semid,&sop,1);
}

/*********************************************************************
 * @fn      Sem_Init
 *
 * @brief   初始化所有信号量
 *
 * @param   none
 *
 * @return  none
 */
void Sem_Init(void)
{
	key_t key;
	union semun sem_un;

	key = ftok("QT", QT_MSG_QUEUE_KEY);
	g_sem_id = semget(key, SEM_NUM, IPC_CREAT|0664);
	if(g_sem_id<0)
	{
		sys_error("semget fail");
	}

	//消息队列
	sem_un.val = 1;
	semctl(g_sem_id, sem_msg_queue_qt_id, SETVAL, sem_un);

	//消息写入
	sem_un.val = 0;
	semctl(g_sem_id, sem_msg_fs_led_arraval_id, SETVAL, sem_un);

	//消息读出
	sem_un.val = 0;
	semctl(g_sem_id, sem_led_handler_id, SETVAL, sem_un);

	//串口消息到达
	sem_un.val = 0;
	semctl(g_sem_id, sem_ms_zb_led_arraval_id, SETVAL, sem_un);

	//串口写入
	sem_un.val = 0;
	semctl(g_sem_id, sem_uart_write_id, SETVAL, sem_un);

	//串口读出
	sem_un.val = 0;
	semctl(g_sem_id, sem_uart_msg_handle_id, SETVAL, sem_un);

	//接收消息数组读写
	sem_un.val = 1;
	semctl(g_sem_id, sem_uart_rec_dat_wr_id, SETVAL, sem_un);

	//数据库操作读写锁
	sem_un.val = 1;
	semctl(g_sem_id, sem_sqlite_wr_id, SETVAL, sem_un);

    //设备在线列表发送
	sem_un.val = 0;
	semctl(g_sem_id, sem_send_dev_online_list, SETVAL, sem_un);
	
	//设备配置列表发送
	sem_un.val = 0;
	semctl(g_sem_id, sem_send_dev_cfg_list, SETVAL, sem_un);
	
	//定时任务消息发送
	sem_un.val = 0;
	semctl(g_sem_id, sem_alarm_task_list, SETVAL, sem_un);
	
	//删除一个定时任务
	sem_un.val = 0;
	semctl(g_sem_id, sem_del_alarm_task, SETVAL, sem_un);
	
	//更新定时任务链表
	sem_un.val = 0;
	semctl(g_sem_id, sem_update_alarm_task, SETVAL, sem_un);
	
}

/*********************************************************************
 * @fn      Msg_queue_Init
 *
 * @brief   初始化消息队列 用于QT进程、CGI接口与主程序进行通信
 *
 * @param   none
 *
 * @return  none
 */
void Msg_queue_Init(none)
{
	g_msgid = msgget((key_t)QT_MSG_QUEUE_KEY, 0666 | IPC_CREAT);
	if(g_msgid == -1)
	{
		sys_error("Msg_queue_Init:msgget fail");
	}
}

/*********************************************************************
 * @fn      Msg_queue_del
 *
 * @brief   删除消息队列
 *
 * @param   none
 *
 * @return  none
 */
void Msg_queue_del()
{
	int ret;
	ret = msgctl(g_msgid, IPC_RMID, 0);
	if(ret == -1)
	{
		sys_error("msgctl fail");
	}
}

/*********************************************************************
 * @fn      str_transition_mac
 *
 * @brief   字符串转mac地址
 *
 * @param   dev_str_mac:字符串 dev_mac:mac地址
 *
 * @return  none
 */
void str_transition_mac(const char *dev_str_mac, char *dev_mac)
{
	int i,j;
	int Hbit,Lbit;
	
	char x_scale[]="0123456789ABCDEF";
	
	for(i=0,j=0; i<8; ++i)
	{
		Hbit = dev_str_mac[i]/16;
		Lbit = dev_str_mac[i]%16;
		
		dev_mac[j]   = x_scale[Hbit];
		dev_mac[j+1] = x_scale[Lbit];
		j            = j+2;
		
		if(i<7)
		{
			dev_mac[j++] = ':';
		}
	}
	
	dev_mac[j] = '\0';
}

/*********************************************************************
 * @fn      mac_transition_str
 *
 * @brief   mac地址转字符串
 *
 * @param   dev_str_mac:字符串 dev_mac:mac地址
 *
 * @return  none
 */
void mac_transition_str(char *dev_str_mac, const char *dev_mac)
{
	int i,j;
	int Hbit,Lbit;
	
	for(i=0,j=0; i<8; ++i)
	{
		if(dev_mac[j]>='0'&&dev_mac[j]<='9')
		{
			Hbit = (dev_mac[j]-'0')*16;
		}
		else if(dev_mac[j]>='A'&&dev_mac[j]<='F')
		{
			Hbit = (dev_mac[j]-'A'+10)*16;
		}
		
		if(dev_mac[j+1]>='0'&&dev_mac[j+1]<='9')
		{
			Lbit = (dev_mac[j+1]-'0');
		}
		else if(dev_mac[j+1]>='A'&&dev_mac[j+1]<='F')
		{
			Lbit = (dev_mac[j+1]-'A'+10);
		}
		
		j += 3;
		
		dev_str_mac[i] = Hbit+Lbit;
	}
	
	dev_str_mac[i] = '\0';
}

int str_to_int(const char *buf)
{
    int i=0,result=0;

    while(buf[i]!='\0')
    {
        result = (result*10)+(buf[i]-'0');
        i++;
    }

    return result;
}
